package com.smartinput.voice.controller

import com.smartinput.voice.application.service.VoiceRecognitionTestService
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import org.springframework.web.multipart.MultipartFile
import java.io.File
import java.nio.file.Files
import java.nio.file.Paths

/**
 * 语音识别测试控制器
 * 
 * 提供API接口用于：
 * 1. 上传测试音频文件
 * 2. 执行语音识别测试
 * 3. 获取测试结果
 */
@RestController
@RequestMapping("/api/voice/test")
class VoiceTestController {

    @Autowired
    private lateinit var voiceTestService: VoiceRecognitionTestService
    
    private val logger = LoggerFactory.getLogger(VoiceTestController::class.java)
    
    // 测试音频文件存储目录
    private val testAudioDir = "test-audio"
    
    init {
        // 确保测试音频目录存在
        val dir = File(testAudioDir)
        if (!dir.exists()) {
            dir.mkdirs()
            logger.info("创建测试音频目录: ${dir.absolutePath}")
        }
    }
    
    /**
     * 获取可用的测试音频文件列表
     */
    @GetMapping("/audio-files")
    fun getTestAudioFiles(): ResponseEntity<List<AudioFileInfo>> {
        return try {
            val audioFiles = File(testAudioDir).listFiles { file ->
                file.isFile && (file.extension.lowercase() in listOf("wav", "mp3", "m4a"))
            }?.map { file ->
                AudioFileInfo(
                    filename = file.name,
                    path = file.absolutePath,
                    size = file.length(),
                    lastModified = file.lastModified()
                )
            } ?: emptyList()
            
            ResponseEntity.ok(audioFiles)
        } catch (e: Exception) {
            logger.error("获取测试音频文件列表失败", e)
            ResponseEntity.internalServerError().build()
        }
    }
    
    /**
     * 上传测试音频文件
     */
    @PostMapping("/upload-audio")
    fun uploadTestAudio(
        @RequestParam("file") file: MultipartFile,
        @RequestParam("expectedText", required = false) expectedText: String?
    ): ResponseEntity<UploadResponse> {
        return try {
            if (file.isEmpty) {
                return ResponseEntity.badRequest().body(
                    UploadResponse(false, "文件为空", null)
                )
            }
            
            val filename = file.originalFilename ?: "unknown.wav"
            val targetFile = File(testAudioDir, filename)
            
            // 保存文件
            Files.copy(file.inputStream, targetFile.toPath())
            
            logger.info("测试音频文件上传成功: ${targetFile.absolutePath}, 大小: ${file.size} bytes")
            
            // 如果提供了期望文本，保存到同名的txt文件
            if (!expectedText.isNullOrBlank()) {
                val textFile = File(testAudioDir, "${filename.substringBeforeLast('.')}.txt")
                textFile.writeText(expectedText)
                logger.info("保存期望文本到: ${textFile.absolutePath}")
            }
            
            ResponseEntity.ok(
                UploadResponse(
                    success = true,
                    message = "文件上传成功",
                    audioFileInfo = AudioFileInfo(
                        filename = filename,
                        path = targetFile.absolutePath,
                        size = file.size,
                        lastModified = System.currentTimeMillis()
                    )
                )
            )
        } catch (e: Exception) {
            logger.error("上传测试音频文件失败", e)
            ResponseEntity.internalServerError().body(
                UploadResponse(false, "上传失败: ${e.message}", null)
            )
        }
    }
    
    /**
     * 执行单个音频文件的识别测试
     */
    @PostMapping("/run-single")
    fun runSingleTest(@RequestBody request: SingleTestRequest): ResponseEntity<VoiceRecognitionTestService.TestResult> {
        return try {
            logger.info("开始执行单个音频测试: ${request.audioFile}")
            
            // 验证音频文件路径
            val audioFile = if (request.audioFile.startsWith("/") || request.audioFile.contains(":")) {
                // 绝对路径
                request.audioFile
            } else {
                // 相对路径，添加测试目录前缀
                File(testAudioDir, request.audioFile).absolutePath
            }
            
            val config = VoiceRecognitionTestService.TestConfig(
                audioFile = audioFile,
                expectedText = request.expectedText,
                chunkSize = request.chunkSize ?: 3200,
                intervalMs = request.intervalMs ?: 200,
                timeoutSeconds = request.timeoutSeconds ?: 30
            )
            
            val result = voiceTestService.runSingleTest(config)
            ResponseEntity.ok(result)
            
        } catch (e: Exception) {
            logger.error("执行单个测试失败", e)
            ResponseEntity.internalServerError().body(
                VoiceRecognitionTestService.TestResult(
                    testId = "error",
                    audioFile = request.audioFile,
                    expectedText = request.expectedText,
                    actualText = "",
                    confidence = 0.0,
                    success = false,
                    errorMessage = e.message,
                    duration = 0,
                    audioSize = 0,
                    audioLength = 0.0
                )
            )
        }
    }
    
    /**
     * 执行批量测试
     */
    @PostMapping("/run-batch")
    fun runBatchTest(@RequestBody request: BatchTestRequest): ResponseEntity<BatchTestResponse> {
        return try {
            logger.info("开始执行批量测试，共${request.tests.size}个文件")
            
            val results = mutableListOf<VoiceRecognitionTestService.TestResult>()
            var successCount = 0
            
            request.tests.forEachIndexed { index, testConfig ->
                logger.info("执行第${index + 1}/${request.tests.size}个测试: ${testConfig.audioFile}")
                
                val config = VoiceRecognitionTestService.TestConfig(
                    audioFile = if (testConfig.audioFile.startsWith("/") || testConfig.audioFile.contains(":")) {
                        testConfig.audioFile
                    } else {
                        File(testAudioDir, testConfig.audioFile).absolutePath
                    },
                    expectedText = testConfig.expectedText,
                    chunkSize = testConfig.chunkSize ?: 3200,
                    intervalMs = testConfig.intervalMs ?: 200,
                    timeoutSeconds = testConfig.timeoutSeconds ?: 30
                )
                
                val result = voiceTestService.runSingleTest(config)
                results.add(result)
                
                if (result.success) {
                    successCount++
                }
                
                // 在测试之间添加间隔，避免过快的请求
                if (index < request.tests.size - 1) {
                    Thread.sleep(2000) // 2秒间隔
                }
            }
            
            val response = BatchTestResponse(
                totalTests = request.tests.size,
                successCount = successCount,
                failureCount = request.tests.size - successCount,
                successRate = successCount.toDouble() / request.tests.size,
                results = results
            )
            
            logger.info("批量测试完成: ${successCount}/${request.tests.size} 成功")
            ResponseEntity.ok(response)
            
        } catch (e: Exception) {
            logger.error("执行批量测试失败", e)
            ResponseEntity.internalServerError().build()
        }
    }
    
    /**
     * 使用预设测试套件
     */
    @PostMapping("/run-preset")
    fun runPresetTest(): ResponseEntity<BatchTestResponse> {
        return try {
            // 创建预设测试配置
            val presetTests = createPresetTests()
            
            if (presetTests.isEmpty()) {
                return ResponseEntity.badRequest().body(
                    BatchTestResponse(0, 0, 0, 0.0, emptyList())
                )
            }
            
            val batchRequest = BatchTestRequest(presetTests)
            runBatchTest(batchRequest)
            
        } catch (e: Exception) {
            logger.error("执行预设测试失败", e)
            ResponseEntity.internalServerError().build()
        }
    }
    
    /**
     * 创建预设测试配置
     */
    private fun createPresetTests(): List<TestConfigItem> {
        val tests = mutableListOf<TestConfigItem>()
        
        // 扫描测试音频目录
        val audioDir = File(testAudioDir)
        if (!audioDir.exists()) {
            return tests
        }
        
        audioDir.listFiles { file ->
            file.isFile && file.extension.lowercase() in listOf("wav", "mp3", "m4a")
        }?.forEach { audioFile ->
            // 查找对应的期望文本文件
            val textFile = File(audioDir, "${audioFile.nameWithoutExtension}.txt")
            val expectedText = if (textFile.exists()) {
                textFile.readText().trim()
            } else {
                "测试音频" // 默认期望文本
            }
            
            tests.add(
                TestConfigItem(
                    audioFile = audioFile.name,
                    expectedText = expectedText,
                    chunkSize = 3200,
                    intervalMs = 200,
                    timeoutSeconds = 30
                )
            )
        }
        
        return tests
    }
    
    // 数据类定义
    data class AudioFileInfo(
        val filename: String,
        val path: String,
        val size: Long,
        val lastModified: Long
    )
    
    data class UploadResponse(
        val success: Boolean,
        val message: String,
        val audioFileInfo: AudioFileInfo?
    )
    
    data class SingleTestRequest(
        val audioFile: String,
        val expectedText: String,
        val chunkSize: Int? = 3200,
        val intervalMs: Long? = 200,
        val timeoutSeconds: Int? = 30
    )
    
    data class TestConfigItem(
        val audioFile: String,
        val expectedText: String,
        val chunkSize: Int? = 3200,
        val intervalMs: Long? = 200,
        val timeoutSeconds: Int? = 30
    )
    
    data class BatchTestRequest(
        val tests: List<TestConfigItem>
    )
    
    data class BatchTestResponse(
        val totalTests: Int,
        val successCount: Int,
        val failureCount: Int,
        val successRate: Double,
        val results: List<VoiceRecognitionTestService.TestResult>
    )
}
